package org.compiere.process;

import java.util.List;
import java.util.Properties;

import org.adempiere.exceptions.AdempiereException;
import org.compiere.apps.IProcessParameter;
import org.compiere.apps.ProcessCtl;
import org.compiere.apps.ProcessParameterPanel;
import org.compiere.model.I_BPM_FormCell;
import org.compiere.model.I_BPM_VersionBudget;
import org.compiere.model.MBPMForm;
import org.compiere.model.MBPMFormCell;
import org.compiere.model.MBPMFormLine;
import org.compiere.model.MBPMFormValues;
import org.compiere.model.MBPMProject;
import org.compiere.model.MBPMProjectAgreement;
import org.compiere.model.MBPMValidationSet;
import org.compiere.model.MBPMValidationSetLine;
import org.compiere.model.Query;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;

public class BPM_FormValidation extends SvrProcess {

	/** Current context		*/
	private Properties m_ctx;
	/**	 */
	private I_BPM_VersionBudget version = null;
	private int AGR_Dispatcher_ID = 0;
	@Override
	protected void prepare() {
		log.info("Send Mail: beginning of the budget");
		m_ctx = getCtx();
		MBPMProjectAgreement projectAgreement = new MBPMProjectAgreement(m_ctx, getRecord_ID(), get_TrxName());
		AGR_Dispatcher_ID = projectAgreement.get_ValueAsInt("AGR_Dispatcher_ID");
		version = projectAgreement.getBPM_Project().getBPM_VersionBudget();
		 
	}

	@Override
	protected String doIt() throws Exception {
		/** 
		 *  проверка бюджетных форм Begin
		 * */
		MBPMForm form = null;
		MBPMForm form1 = null;
		MBPMFormLine formLine = null;
		MBPMFormLine formLine1 = null;
		MBPMFormCell cell = null;
		MBPMFormCell cell1 = null;
		String cellValue = "0";
		String cellValue1 = "0";
		MBPMProject[] projects = null;
		
		MBPMValidationSet[] validationSets = MBPMValidationSet.getMbpmValidationSets(version.getBPM_VersionBudget_ID());
		
		if(validationSets.length<1)
		{
			throw new AdempiereException("Не найдено ни одной настройки по проверке");
		}
		else
		{
			for(MBPMValidationSet validationSet: validationSets)
			{
				projects = MBPMProject.getWorkProject(m_ctx, validationSet.getBPM_VersionBudget_ID(), get_TrxName());
				if(projects.length>0){
					form = new MBPMForm(m_ctx, validationSet.getBPM_Form_ID(), get_TrxName());
					form1 = new MBPMForm(m_ctx, validationSet.getBPM_Form1_ID(), get_TrxName());
					formLine = new MBPMFormLine(m_ctx, validationSet.getBPM_FormLine_ID(), get_TrxName());
					formLine1 = new MBPMFormLine(m_ctx, validationSet.getBPM_FormLine1_ID(), get_TrxName());
					
					for(MBPMValidationSetLine validationSetLine: validationSet.getLines(true))
					{
						cellValue = "0";
						cellValue1 = "0";
						cell = MBPMFormCell.getCell(m_ctx, validationSetLine.getBPM_FormColumn_ID(), formLine.get_ID(), get_TrxName());
						cell1 = MBPMFormCell.getCell(m_ctx, validationSetLine.getBPM_FormColumn1_ID(), formLine1.get_ID(), get_TrxName());
						
						String value = MBPMFormValues.getCellValue(formLine.get_ID(), validationSetLine.getBPM_FormColumn_ID()
													, projects[0].get_ID(), Env.getAD_Org_ID(m_ctx), Env.getAD_Client_ID(m_ctx));
						if(value!=null && value.length()>0)
							cellValue = value;
						
						String value1 = MBPMFormValues.getCellValue(formLine1.get_ID(), validationSetLine.getBPM_FormColumn1_ID()
								, projects[0].get_ID(), Env.getAD_Org_ID(m_ctx), Env.getAD_Client_ID(m_ctx));
						
						if(value1!=null && value1.length()>0)
							cellValue1 = value1;
						
						if(cellValue.equals(cellValue1))
							continue;
						else
						{
							throw new AdempiereException(projects[0].getName()+": "+form.getName()+" - "+formLine.getName()+" - "+cell.getBSC_Parameter().getName()
									+" = "+cellValue+" не соответсвует " +form1.getName()+" - "+formLine1.getName()
									+" - "+cell1.getBSC_Parameter().getName()+" = "+cellValue1);
						}
					}
				}
				else{
					return "Рабочий проект не найден!";
				}
			}
		}
		//TODO Когда придумаем как обойти NULL и 0 нужно дописать проверку заполнения ячеек
		//TODO Придумано так: если значение обязательного поля 0 тогда нужно поставить два или более ноля
		int i =0;
		String errorList = "";
		
		MBPMFormCell[] formCells = getMandatoryCells();
		if(formCells.length<1)
		{
			throw new AdempiereException("Не найдено ни одного обязательного поля");
		}
		else
		{
			for(MBPMFormCell mandatoryCell: formCells)
			{
				String manCellValue = null;
				manCellValue = MBPMFormValues.getCellValue(mandatoryCell.getBPM_FormLine_ID()
						, mandatoryCell.getBPM_FormColumn_ID()
						, MBPMProject.getWorkProject(m_ctx, 
								new MBPMForm(m_ctx, MBPMFormCell.getBPM_Form_ID(mandatoryCell.get_ID()), get_TrxName()).getBPM_VersionBudget_ID()
								, get_TrxName())[0].get_ID()
						, Env.getAD_Org_ID(m_ctx), Env.getAD_Client_ID(m_ctx));
				if(manCellValue.length()==0 || manCellValue==null || manCellValue.equals("0")){
					if(i!=0){
						errorList = errorList+"\n";
					}
					errorList = errorList  + "Форма:"+new MBPMForm(m_ctx, MBPMFormCell.getBPM_Form_ID(mandatoryCell.get_ID()), get_TrxName()).getName() +" Линия: №"
							+mandatoryCell.getBPM_FormLine().getLineNo()+"-"+mandatoryCell.getBPM_FormLine().getName()+" Ячейка: "
								+mandatoryCell.getBPM_FormColumn().getName()+"="+manCellValue;
					i++;
				}	
			}
			if(errorList.length()!=0)
				throw new AdempiereException("Следующие обязательные не заполнены:\n"+errorList);
			/** 
			 *  проверка бюджетных форм End
			 * */
		};
		
		//then we start agreement process
	//  Prepare Process
		String sql_ = "SELECT R.AD_PROCESS_ID FROM AGR_DISPATCHER T \n" +
				" JOIN AGR_AGREEMENT R ON R.AGR_AGREEMENT_ID=T.AGR_AGREEMENT_ID \n" +
				" WHERE T.AGR_DISPATCHER_ID="+AGR_Dispatcher_ID;
		
		ProcessInfo pi = new ProcessInfo ("The process of agreement", DB.getSQLValue(get_TrxName(), sql_));
		pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
		pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));	
		pi.setRecord_ID(getRecord_ID());
		pi.setTable_ID(getTable_ID());	
		
		//	Execute Process
		ProcessParameterPanel pu = new ProcessParameterPanel(0, pi);
		ProcessCtl.process(null, 0, (IProcessParameter) pu, pi, null);
		
		return Msg.translate(m_ctx, "Success");
	}
	
	public MBPMFormCell[] getMandatoryCells()
	{
		List<MBPMFormCell> list = new Query(Env.getCtx(), I_BPM_FormCell.Table_Name, "IsMandatory='Y'",get_TrxName())
		.setOnlyActiveRecords(true)
		.list();

		return list.toArray(new MBPMFormCell[list.size ()]);
	}

}
